<script setup lang="ts">
import { ref, computed } from 'vue'
import { CONDIMENT_MAP, TECHNIQUES_MAP, RARITY_MAP, COLLECT_MAP } from '@/stores/mappings'
import { getStringKeys, getNumericKeys } from '@/utils/tools'

import type { SelectOption } from 'naive-ui'
import type { ChefSettings, Techniques, Condiment, Collect } from './types'

interface RarityOption extends SelectOption {
  value: number
}

interface TechniquesOption extends SelectOption {
  value: Techniques
}

interface CondimentOption extends SelectOption {
  value: Condiment
}

interface CollectOption extends SelectOption {
  value: Collect
}

const props = defineProps<{
  settings: ChefSettings
}>()

const emit = defineEmits<{
  (e: 'update:settings', value: ChefSettings): void
}>()

const rarityOptions = ref<RarityOption[]>(
  getNumericKeys(RARITY_MAP).map((key) => ({
    label: RARITY_MAP[key],
    value: key,
  })),
)

const techniquesOptions = ref<TechniquesOption[]>(
  getStringKeys(TECHNIQUES_MAP).map((key) => ({
    label: TECHNIQUES_MAP[key],
    value: key,
  })),
)

const condimentOptions = ref<CondimentOption[]>(
  getStringKeys(CONDIMENT_MAP).map((key) => ({
    label: CONDIMENT_MAP[key],
    value: key,
  })),
)

const collectOptions = ref<CollectOption[]>(
  getStringKeys(COLLECT_MAP).map((key) => ({
    label: COLLECT_MAP[key],
    value: key,
  })),
)

const rarityDisplay = computed(() => {
  const { rarity } = props.settings
  if (!rarity.length) return ''
  return rarityOptions.value
    .filter((f) => rarity.includes(f.value))
    .map((m) => m.label)
    .join('&')
})

const techniquesDisplay = computed(() => {
  const { techniques } = props.settings
  if (!techniques.length) return ''
  return techniquesOptions.value
    .filter((f) => techniques.includes(f.value))
    .map((m) => m.label)
    .join('&')
})

const condimentDisplay = computed(() => {
  const { condiment } = props.settings
  if (!condiment.length) return ''
  return condimentOptions.value
    .filter((f) => condiment.includes(f.value))
    .map((m) => m.label)
    .join('&')
})

const collectDisplay = computed(() => {
  const { collect } = props.settings
  if (!collect.length) return ''
  return collectOptions.value
    .filter((f) => collect.includes(f.value))
    .map((m) => m.label)
    .join('&')
})

function updateCondiment(value: Condiment[]) {
  const condiment = value.length > 0 ? [value[value.length - 1]] : []
  emit('update:settings', { ...props.settings, condiment })
}
</script>

<template>
  <n-flex>
    <n-popselect
      class="w-[100px]"
      v-model:value="settings.rarity"
      :options="rarityOptions"
      trigger="hover"
      multiple
    >
      <n-button class="min-w-[100px]">
        <span class="mx-[4px]">星级</span>
        <n-gradient-text type="info">{{ rarityDisplay }}</n-gradient-text>
      </n-button>
    </n-popselect>
    <n-popselect
      class="w-[100px]"
      v-model:value="settings.techniques"
      :options="techniquesOptions"
      trigger="hover"
      multiple
    >
      <n-button class="min-w-[100px]">
        <span class="mx-[4px]">技法</span>
        <n-gradient-text type="info">{{ techniquesDisplay }}</n-gradient-text>
      </n-button>
    </n-popselect>
    <n-popselect
      class="w-[100px]"
      :value="settings.condiment"
      :options="condimentOptions"
      trigger="hover"
      multiple
      :on-update:value="updateCondiment"
    >
      <n-button class="min-w-[100px]">
        <span class="mx-[4px]">调料</span>
        <n-gradient-text type="info">{{ condimentDisplay }}</n-gradient-text>
      </n-button>
    </n-popselect>
    <n-popselect
      class="w-[100px]"
      v-model:value="settings.collect"
      :options="collectOptions"
      trigger="hover"
      multiple
    >
      <n-button class="min-w-[100px]">
        <span class="mx-[4px]">探索</span>
        <n-gradient-text type="info">{{ collectDisplay }}</n-gradient-text>
      </n-button>
    </n-popselect>
  </n-flex>
</template>

<style lang="scss" scoped></style>
